import YNavBar from './Views/YNavBar.vue'
import YRow from './Views/YRow.vue'
import YColumn from './Views/YColumn.vue'
import YExpanded from './Views/YExpanded.vue'
import YContent from './Views/YContent.vue'
import YPage from './Views/YPage.vue'
import store from "../../store";

let $this;

export default {
    DEBUG: false,
    webName: "YFree_Uniapp",
    themeColor: "#000000",
    IP: "",
    statusBar: "",
    encryptParamsAble: false,
    encryptParamsKey: "0000000000000000",
    onYHTTPHeader: () => {
    },
    yInit: function (app, onYConfig) {
        $this = this;
        if ($this.yIsApp()) {
            $this.ySendEvent("yGetDebug", null, (res) => $this.DEBUG = (res === "debug"));
            $this.ySendEvent("yGetIP", null, (res) => $this.IP = res);
            $this.ySendEvent("yGetAppName", null, (res) => $this.webName = res);
        }
        onYConfig($this);
        app.use(store);
        app.config.globalProperties.yFree = $this;
        app.component('YNavBar', YNavBar);
        app.component('YRow', YRow);
        app.component('YColumn', YColumn);
        app.component('YExpanded', YExpanded);
        app.component('YPage', YPage);
        app.component('YContent', YContent);
    },
    yIsApp: function () {
        //#ifdef APP-PLUS || APP-PLUS-NVUE
        return uni.getSystemInfoSync().platform === "android" || uni.getSystemInfoSync().platform === "ios";
        //#endif
        return false;
    },
    yStatuBarHeight: function () {
        return uni.getSystemInfoSync().statusBarHeight;
    },
    yNavBarHeight: function () {
        return uni.getSystemInfoSync().platform === "ios" ? 44 : 48;
    },
    yAppBarHeight: function () {
        return $this.yStatuBarHeight() + $this.yNavBarHeight();
    },
    getAppHttpHeader: function () {
        return new Promise((resolve, reject) => {
            $this.ySendEvent("yGetHttpHeader", null, (res) => {
                resolve(res);
            });
        });
    },
    yPostRetryTimes: 0,
    yPost: async function (jkid, params, onSuccess, onFail = null, showProgress = true, showErrorToast = true) {
        if (showProgress) $this.yShowProgress();
        if ($this.yIsEmpty($this.IP)) {
            if ($this.yPostRetryTimes >= 3) {
                $this.yPostRetryTimes = 0;
                if (showProgress) $this.yDismissProgress();
                if (onFail) onFail(-999, "请正确配置YFree：IP");
            } else {
                $this.yRunOnDelay(500, () => {
                    $this.yPostRetryTimes++;
                    $this.yPost(jkid, params, onSuccess, onFail, showProgress, showErrorToast);
                });
            }
            return;
        }
        $this.yPostRetryTimes = 0;
        $this.yLog(jkid + ":request:" + ($this.yIsEmpty(params) ? "无入参" : $this.yToJson(params)));
        return uni.request({
            method: "POST",
            url: $this.IP,
            data: {
                jkid: jkid,
                jkparam: $this.encryptParamsAble ? $this.yAesEncrypt($this.yToJson(params), $this.encryptParamsKey) : $this.yToJson(params)
            },
            header: $this.yIsApp() ? $this.yFromJson(await $this.getAppHttpHeader()) : $this.onYHTTPHeader(),
            timeout: 15000,
            dataType: "text",
            responseType: "text",
            success: function (res) {
                let response = $this.encryptParamsAble ? $this.yFromJson($this.yAesEncrypt(res.data,
                    $this.encryptParamsKey)) : $this.yFromJson(res.data);
                $this.yLog(jkid + ":responseSuccess:" + $this.yToJson(response));
                if (showProgress) $this.yDismissProgress();
                if (response != "") {
                    try {
                        let root = response.root;
                        if (root.code == 1) {
                            onSuccess(root.result);
                        } else {
                            if (showErrorToast) $this.yToast($this.DEBUG ? "网络请求回执message：\n" + root.message : root.message);
                            if (onFail != null) onFail(root.code, root.message);
                        }
                    } catch (e) {
                        let msg = $this.DEBUG ? "网络请求回执message解析异常，异常信息：\n" + e.toString() : "网络请求错误，请重试";
                        if (showErrorToast) $this.yToast(msg);
                        if (onFail != null) onFail("", msg);
                    }
                } else {
                    if (showErrorToast) $this.yToast($this.DEBUG ? "网络请求回执message解析异常，响应字符串：\n（空）" : "网络请求错误，请重试");
                    if (onFail != null) onFail("", "");
                }
            }, fail: function (res) {
                $this.yLog(jkid + ":responseFailure:" + "网络请求异常！！！\tMsg:" + res.errMsg);
                if (showProgress) $this.yDismissProgress();
                if (showErrorToast) $this.yToast($this.DEBUG ? "网络请求异常！！！\nMsg:" + res.errMsg : "网络请求错误，请重试");
                if (onFail) onFail(null, res.errMsg);
            }
        })
    },
    setTitle: function (title) {
        uni.setNavigationBarTitle({
            title: title
        });
    },
    yOpenBrowser: function (url) {
        $this.ySendEvent("yOpenBrowser", url);
    },
    wxParse: function (context, name, html) {
        WxParse.wxParse(name, 'html', html, context);
    },
    ySave: function (key, data) {
        uni.setStorageSync(key, data);
    },
    yRead: function (key) {
        return uni.getStorageSync(key);
    },
    yDelete: function (key) {
        uni.removeStorageSync(key);
    },
    yIntent: function (page, param = "", type = 1) {
        param = (param == null ? "" : param);
        switch (type) {
            case 0: //替换
                uni.redirectTo({
                    url: page + param
                });
                break;
            case 1: //前进
                uni.navigateTo({
                    url: page + param
                });
                break;
            case 2: //TabBar
                uni.switchTab({
                    url: page + param
                });
                break;
            case 3: //重启并打开
                uni.reLaunch({
                    url: page + param
                });
                break;
        }
    },
    yFinishToHome: function () {
        uni.navigateBack({
            delta: 99
        });
    },
    yFinishApplication: function () {
        // uni.navigateBack({
        //     delta: 99
        // });
        plus.runtime.quit();
        return true;
    },
    yFinish: function (delta = 1) {
        uni.navigateBack({
            delta: delta
        });
    },
    yRefresh: function (context) {
        context.setData(context.data);
    },
    yRunOnDelay: function (delay, action) {
        return setTimeout(action, delay);
    },
    yRunOnLoop: function (loopTime, action, firstDelay = false) {
        if (!firstDelay) action();
        return setInterval(action, loopTime);
    },
    yStopRun: function (task) {
        clearTimeout(task);
        clearInterval(task);
    },
    yIsEmpty: function (obj) {
        return obj == null || obj.toString() === "";
    },
    yIsNotEmpty: function (obj) {
        return obj != null && obj.toString() !== "";
    },
    yCopy: function (content) {
        return $this.ySendEvent("yCopy", content);
    },
    yLog: function (content) {
        if ($this.DEBUG)
            if ($this.yIsApp())
                $this.ySendEvent("yLog", content);
            else
                console.log(content);
    },
    yToast: function (msg) {
        if ($this.yIsApp())
            $this.ySendEvent("yToast", msg);
        else
            uni.showToast({
                title: msg.toString(),
                icon: 'none',
                position: "bottom",
            });
    },
    yShowProgress: function (title = "拼命加载中···") {
        // uni.showNavigationBarLoading();
        uni.hideLoading();
        uni.showLoading({
            title: title,
            mask: true
        });
    },
    yDismissProgress: function () {
        // uni.hideNavigationBarLoading();
        uni.hideLoading();
    },
    yShowBuilder: function (msg, callback, showCancel = true, btn = "确定") {
        uni.showModal({
            title: $this.webName + "提示",
            content: msg,
            showCancel: showCancel,
            cancelText: '取消',
            cancelColor: $this.themeColor,
            confirmText: btn,
            confirmColor: $this.themeColor,
            success: function (res) {
                callback(res.confirm);
            }
        });
    },
    yShowActionSheet: function (itemList, callback) {
        uni.showActionSheet({
            itemList: itemList,
            itemColor: $this.themeColor,
            success: function (res) {
                callback(res.tapIndex);
            }
        })
    },
    yToJson: function (obj) {
        return JSON.stringify(obj);
    },
    yFromJson: function (json) {
        return $this.yIsEmpty(json) ? null : JSON.parse(json);
    },
    yRegisterEvent: function (callback) {
        if ($this.yIsApp())
            uni.onNativeEventReceive((event, data) => {
                switch (event) {
                    case "runUniapp":
                        $this.yToast("原生代码调用YFree_Uniapp");
                        break;
                    default:
                        callback(event, data)
                }
            });
    },
    ySendEvent: function (event, data, callback = (res) => {
    }) {
        if ($this.yIsApp())
            uni.sendNativeEvent(event, data, callback);
    },
    /* BroadCast */
    __notices: [],
    yRegisterReceiver: function (name, selector = (params) => {
    }) {
        if (name && selector)
            $this.__notices.push({
                name: name,
                selector: selector
            });
    },
    yDeleteReceiver: function (name) {
        for (let i = 0; i < $this.__notices.length; i++)
            if ($this.__notices[i].name === name) {
                $this.__notices.splice(i, 1);
                return;
            }
    },
    ySendBroadcast: function (name, params = {}) {
        if ($this.__notices.length === 0) return;
        for (let i = 0; i < $this.__notices.length; i++)
            if ($this.__notices[i].name === name) $this.__notices[i].selector(params);
    },
    /* Base64 */
    base64_encode: function (str) { // 编码，配合encodeURIComponent使用
        var c1, c2, c3;
        var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        var i = 0,
            len = str.length,
            strin = '';
        while (i < len) {
            c1 = str.charCodeAt(i++) & 0xff;
            if (i == len) {
                strin += base64EncodeChars.charAt(c1 >> 2);
                strin += base64EncodeChars.charAt((c1 & 0x3) << 4);
                strin += "==";
                break;
            }
            c2 = str.charCodeAt(i++);
            if (i == len) {
                strin += base64EncodeChars.charAt(c1 >> 2);
                strin += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
                strin += base64EncodeChars.charAt((c2 & 0xF) << 2);
                strin += "=";
                break;
            }
            c3 = str.charCodeAt(i++);
            strin += base64EncodeChars.charAt(c1 >> 2);
            strin += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
            strin += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
            strin += base64EncodeChars.charAt(c3 & 0x3F)
        }
        return strin
    },
    base64_decode: function (input) { // 解码，配合decodeURIComponent使用
        let base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        let output = "";
        let chr1, chr2, chr3;
        let enc1, enc2, enc3, enc4;
        let i = 0;
        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
        while (i < input.length) {
            enc1 = base64EncodeChars.indexOf(input.charAt(i++));
            enc2 = base64EncodeChars.indexOf(input.charAt(i++));
            enc3 = base64EncodeChars.indexOf(input.charAt(i++));
            enc4 = base64EncodeChars.indexOf(input.charAt(i++));
            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;
            output = output + String.fromCharCode(chr1);
            if (enc3 != 64) output = output + String.fromCharCode(chr2);
            if (enc4 != 64) output = output + String.fromCharCode(chr3);
        }
        return $this.utf8_decode(output);
    },
    utf8_decode: function (utftext) { // utf-8解码
        let string = '';
        let i = 0;
        let c = 0;
        let c1 = 0;
        let c2 = 0;
        while (i < utftext.length) {
            c = utftext.charCodeAt(i);
            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            } else if ((c > 191) && (c < 224)) {
                c1 = utftext.charCodeAt(i + 1);
                string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
                i += 2;
            } else {
                c1 = utftext.charCodeAt(i + 1);
                c2 = utftext.charCodeAt(i + 2);
                string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
                i += 3;
            }
        }
        return string;
    },
}
